package com.douqu.game.main.server;

import com.douqu.game.core.config.FunctionConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.E_CityInitGarrisonType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.ext.BoonInfo;
import com.douqu.game.core.entity.ext.ChallengeInfo;
import com.douqu.game.core.entity.ext.MailInfo;
import com.douqu.game.core.entity.world.WorldRankBean;
import com.douqu.game.core.entity.world.WorldRankData;
import com.douqu.game.core.entity.world.map.CityBean;
import com.douqu.game.core.entity.world.map.WorldMapData;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.FunctionFactory;
import com.douqu.game.core.factory.WorldInfoFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.service.WorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Component
public class ScheduledTask {


    /**
     * 定时保存玩家数据的间隔时间
     * 4分钟
     */
    private final static int SAVE_PLAYER_TIME = 5 * 60 * 1000;

    /**
     * 更新时间
     */
    private final static int UPDATE_TIME = 500;

    /**
     * 每分钟执行一次 刷新所有配置时间的活动是否开启
     */
    private final static int FLUSH_TIME = 60 * 1000;

    @Autowired
    private PlayerService playerService;

    @Autowired
    private WorldService worldService;

    private long flushTime = 0l;

    private int flushHour;

//    @Scheduled(fixedRate = FLUSH_TIME)//每分钟执行一次
    @Scheduled(cron = "0 * * * * ?")
    public void flushTime() throws Exception{
        try {
            if(!GameServer.getInstance().isRunning())
                return;
            Calendar calendar = Calendar.getInstance();
            int second = calendar.get(Calendar.SECOND);
            //加5秒
            calendar.set(Calendar.SECOND, second + 5);
            GameServer.getInstance().getWorldManager().checkFlush(calendar);
        }catch (Exception e){
            LogUtils.errorException(e);
        }
    }

    /**
     * fixedRate 定时执行,不管任务执行时间都是固定间隔时间
     * fixedDelay 会因为每次任务执行时间而打乱定时任务(慎用,最好不要用这种模式)
     *
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = SAVE_PLAYER_TIME, initialDelay = 180000)//延迟3分执行
    public void savePlayer() throws Exception
    {
        try{
            worldService.update();

            playerService.saveOnlinePlayer(false);

            RecordManager.getInstance().save();
        }catch (Exception e) {
            LogUtils.errorException(e);
        }
    }



    int count = 0;

    /**
     * 更新
     *
     * @throws InterruptedException
     */
    @Scheduled(fixedRate = UPDATE_TIME)
    public void updatePlayer() throws Exception
    {
        if(!GameServer.getInstance().isRunning())
            return;
        DataFactory.currentTime = System.currentTimeMillis();
        try{
            if (++count >= 2) {
                count = 0;
                if(LoadManager.loading || LoadManager.updating)
                {
                    LogUtils.warn("更新配置文件或Class中......暂停update");
                    return;
                }

//                int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
//                long now = DataFactory.currentTime;
                GameServer.getInstance().getWorldManager().update(DataFactory.currentTime);
                ServerManager.getInstance().update();
                UpdateManager.getInstance().update(DataFactory.currentTime);
            }
        }catch (Exception e) {
            LogUtils.errorException(e);
        }
    }

    /**
     * 每小时执行一次
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0 * * * ?")
    public void hourUpdate() throws Exception
    {
        Calendar calendar = Calendar.getInstance();
        int minute = calendar.get(Calendar.MINUTE);
        calendar.set(Calendar.MINUTE, minute + 1);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        //long now = DataFactory.currentTime;
        LogUtils.warn("+--------------hour -> " + hour);
        try {

            if(hour == 0)
            {
                //0点
                LogUtils.warn("----------0点执行");
                GameServer.getInstance().getWorldArenaData().reset();
                LogUtils.warn("worldArenaData reset successfully");
                GameServer.getInstance().getWorldOfficialData().reset();
                LogUtils.warn("worldOfficialData reset successfully");
                //GameServer.getInstance().getWorldBossData().reset();
                //LogUtils.warn("worldBossData reset successfully");
                GameServer.getInstance().updateRechargeCount();
                LogUtils.warn("updateRechargeCount reset successfully");
                boolean isFirstSunday = calendar.getFirstDayOfWeek() == 1;
                int weekDay = calendar.get(7);
                if (isFirstSunday) {
                    --weekDay;
                    if (weekDay == 0) {
                        weekDay = 7;
                    }
                }
                //正常周一执行 修复bug 2018年9月11日特殊执行
                if (weekDay == 1){
//                 if(TimeUtils.getWeekDay() == 1)
//                {
                    //周日24点执行，也就是周一0点
                    Map<String,Player> allPlayer = GameServer.getInstance().getWorldManager().getAllPlayerMap();

                    WorldRankData worldRankData = WorldInfoFactory.getInstance().getWorldRankData();
                    List<WorldRankBean> rankBeanList = worldRankData.getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_MAPCURRWEEK);

                    //先进行排行奖励分发
                    Map<String,Player> updateMap = new HashMap<>();
                    if (!allPlayer.isEmpty()){
                        Player player = null;
                        PlayerController playerController = null;
                        if (!rankBeanList.isEmpty()){
                            GameServer.getInstance().getWorldManager().hegemonyRankReward(allPlayer, rankBeanList, updateMap);
                        }
                        for (Player entry:allPlayer.values()){

                            boolean flag = false;
                            playerController = GameServer.getInstance().getWorldManager().getPlayerController(entry.objectIndex);
                            if (playerController != null){
                                player = playerController.getPlayer();
                            }else{
                                player = entry;
                            }
                            if (player.getBonusData().getAuctionReward() != 0 ){
                                player.getBonusData().initAuctionReward();
                                flag = true;
                            }
                            //每周日24点 玩家这周数据代替上周数据，并且清空这周数据
                            //排行榜把本周的前三赋值给上周本周的清空
                            if(!player.getWorldMapKillData().checkMonday()){
                                flag = true;
                            }
                            if (flag){
                                updateMap.put(player.getObjectIndex(),player);
                            }
                        }
                        if (!updateMap.isEmpty()){
                            //执行保存数据库
                            List<Player> updateList = new ArrayList<>(updateMap.values());
                            GameServer.getInstance().savePlayerListSync(updateList, false, BoonInfo.class, ChallengeInfo.class, MailInfo.class);
                        }
                    }
                    //执行worldmap排行顺序
                    GameServer.getInstance().getWorldManager().checkMondy(worldRankData);
                    LogUtils.warn("rank reward successfully!");
                    //boss信息由每日一reset  改为每周一reset
                    GameServer.getInstance().getWorldBossData().reset();
                    LogUtils.warn("worldBossData reset successfully");
                }

                //每日零点执行限时活动邮件发放奖励的功能
                LogUtils.info("开始检测限时活动 ...");
                GameServer.getInstance().getWorldManager().timeLimitActivityCheck(calendar);
                LogUtils.info("限时活动检测完成");

                //每日零点检测开服嘉联华是否发送奖励
                LogUtils.info("开服开服嘉联华活动检测 ...");
                GameServer.getInstance().getWorldManager().timeTopRankCheck();
                LogUtils.info("开服开服嘉联华活动检测完成");

            }
            else if(hour == 4){
                //4点
                List<PlayerController> playerList = GameServer.getInstance().getWorldManager().getPlayerList();
                for (int i = 0; i < playerList.size(); i++) {
                    playerList.get(i).getPlayer().reset();
                }
                LogUtils.warn("4'clock player reset successfully");
                GameServer.getInstance().getWorldManager().rankRewardRest(SGCommonProto.E_RANK_TYPE.RANK_TYPE_WORLDMAP);
                LogUtils.warn("4'clock worldMapTask rank reward successfully");
            }

            //为了方便测试暂时使用 正式服务器
//            LogUtils.info("开始检测限时活动 ...");
//            GameServer.getInstance().getWorldManager().timeLimitActivityCheck(calendar);
//            LogUtils.info("限时活动检测完成");

            //每小时获取一次玩家平均等级
            int averageLevel = playerService.getWorldPlayerAverageLevel(10, 0);
            FunctionConfig config = DataFactory.getInstance().getGameObject(DataFactory.FUNCTION_KEY, FunctionFactory.WORLD_BOSS);
            int bossLv = averageLevel;
            if(config != null){
                bossLv = bossLv < config.lv ? config.lv  + 1 : bossLv;
            }
            WorldInfoFactory.getInstance().getWorldBossData().setAverageLv(bossLv);
            WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData();
            int beforeLevel = worldMapData.getPlayerAverageLevel();
            if(worldMapData.checkFlush(averageLevel))
            {
                worldMapData.setPlayerAverageLevel(averageLevel);
                LogUtils.warn("定时更新大地图所有和平城的驻军开始 -> lv:" + averageLevel);
                for(CityBean cityBean : worldMapData.getCityMap().values())
                {
                    if(cityBean.isPeace() && beforeLevel != averageLevel)
                    {
                        cityBean.initGarrison(E_CityInitGarrisonType.TIMING);
                        LogUtils.warn("城 -> " + cityBean.getConfig().name + " 更新驻军完成!");
                    }
                }
                LogUtils.warn("定时更新大地图所有和平城的驻军完成 ->");
            }

            LogUtils.info("every hour reset all successfully! end !");
            //一小时检测一次是否大地图掉落
            //每小时检测一次争霸赛是否开启或者结束
            GameServer.getInstance().getWorldManager().resetHegemonyInfo(hour);
            LogUtils.info("every hour reset hegemony is start or end! successfully!");

            GameServer.getInstance().getWorldManager().updateWhite();
        }catch (Exception e){
            LogUtils.errorException(e);
            throw e;
        }
//        List<CityDropGroupConfig> dropGroupConfigList = MapUtils.getOtherConfigList();
//        for (CityDropGroupConfig dropConfig:dropGroupConfigList){
//            if (dropConfig.type == E_CityDrop_Flush_Type.CITY_DROP_FLUSH_EVERYDAY.getCode()){
//                if (hour == dropConfig.subtype[0]){
//                    worldMapData.cityDrop(dropConfig, null, null);
//                }
//            }
//            if (dropConfig.type == E_CityDrop_Flush_Type.CITY_DROP_FLUSH_TIMMER.getCode()){
//                if (CoreUtils.timeToLong(now) == dropConfig.subtype[0]){
//                    worldMapData.cityDrop(dropConfig, null, null);
//                }
//            }
//            if (dropConfig.type == E_CityDrop_Flush_Type.CITY_DROP_FLUSH_ACTIVITY.getCode()){
//                if (CoreUtils.longToTime(dropConfig.subtype[0]) <= now
//                        && CoreUtils.longToTime(dropConfig.subtype[1]) > now){
//                    //假定这里含头不含尾
//                    long time = dropConfig.subtype[0];
//                    while (true){
//                        if (time == CoreUtils.timeToLong(now)){
//                            worldMapData.cityDrop(dropConfig, null, null);
//                            break;
//                        }
//                        time += dropConfig.subtype[2];
//                        if (time >= dropConfig.subtype[1]){
//                            break;
//                        }
//                    }
//                }
//            }
//            if (dropConfig.type == E_CityDrop_Flush_Type.CITY_DROP_FLUSH_EVERYWEEK.getCode()){
//                if (CoreUtils.getTodayWeek(now) == dropConfig.subtype[0]){
//                    if (hour == dropConfig.subtype[1]){
//                        worldMapData.cityDrop(dropConfig,null,null);
//                    }
//                }
//            }
//        }
    }

//    /**
//     * 每天执行一次
//     * @throws Exception
//     */
//    @Transactional(rollbackFor = Exception.class)
//    @Scheduled(cron = "0 0 0 * * ?")
//    public void checkOpenServerUpdate() throws Exception {
//        Calendar calendar = Calendar.getInstance();
//        int hour = calendar.get(Calendar.HOUR_OF_DAY);
//        LogUtils.warn("+--------------hour -> " + hour);
//        //每日零点检测排行榜冲榜活动是否发送奖励
//        LogUtils.info("开服冲榜活动检测 ...");
//        GameServer.getInstance().getWorldManager().timeTopRankCheck();
//        LogUtils.info("开服冲榜活动检测完成");
//    }
}